package com.fulihui.wgj.consumer.communication.event;

import com.alibaba.dubbo.config.annotation.Reference;
import com.fulihui.common.constants.PlaceholderConstants;
import com.fulihui.common.enums.CustomMsgTypeEnum;
import com.fulihui.common.enums.EventTypeEnum;
import com.fulihui.common.request.rpc.AppRequest;
import com.fulihui.common.result.rpc.SimpleResult;
import com.fulihui.wgj.consumer.entity.WxUserInfoExp;
import com.fulihui.wgj.consumer.service.ExternalSystemService;
import com.fulihui.wgj.consumer.service.UserService;
import com.fulihui.wgj.consumer.service.WxMsgService;
import com.fulihui.wgj.facade.dto.NotifyUserActivityDTO;
import com.fulihui.wgj.facade.dto.WxQrcodeReplyInfoDTO;
import com.fulihui.wgj.facade.dto.WxSubscribeReplyAdvertDTO;
import com.fulihui.wgj.facade.msg.EventMsg;
import com.fulihui.wgj.facade.request.qrcode.WxQrcodeReplyQueryOneRequest;
import com.fulihui.wgj.facade.request.qrcode.WxQrcodeScanEventRequest;
import com.fulihui.wgj.facade.service.qrcode.WxParamQrcodeService;
import com.fulihui.wgj.facade.service.reply.WxSubscribeAdverseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.near.toolkit.common.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author: LiuJie
 * @version: 2018/7/7 14:08
 * @description: 扫码事件
 */
@Component
@Slf4j
public class QrcodeScanProcessor implements EventMsgProcessor {

    @Autowired
    private ExternalSystemService externalSystemService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Reference(version = "1.0.0")
    private WxParamQrcodeService wxParamQrcodeService;
    @Autowired
    private WxMsgService wxMsgService;
    @Autowired
    private UserService userService;
    @Reference(version = "1.0.0")
    private WxSubscribeAdverseService adverseService;

    @Override
    public void process(EventMsg message) {
        String eventKey = message.getEventKey();
        String openId = message.getFromUserName();
        String appId = message.getAppId();
        if (StringUtils.isBlank(eventKey)
                || StringUtils.isBlank(appId) || StringUtils.isBlank(openId)) {
            log.error("appid、openid 或 eventKey 为空,eventMsg={}", message);
            return;
        }

        log.info(message.getFromUserName() + " ParamQrcodeScan " + message.getToUserName() + "." + eventKey);

        // 获取用户信息
        WxUserInfoExp userInfo = userService.getUserInfo(appId, openId);

        // 回复消息
        replyMsg(userInfo, eventKey);

        threadPoolTaskExecutor.execute(() -> {
            // 参数二维码扫描 记录入库
            WxQrcodeScanEventRequest request = new WxQrcodeScanEventRequest();
            request.setAppId(appId);
            request.setOpenid(openId);
            request.setQrScene(eventKey);
            request.setEventDate(new Date());
            wxParamQrcodeService.saveScanEvent(request);

            // 扫码事件、通知立白
            qrsceneNotifyTheUser(appId, openId, eventKey);
        });

    }

    void replyMsg(WxUserInfoExp user, String eventKey) {
        WxQrcodeReplyQueryOneRequest request = new WxQrcodeReplyQueryOneRequest();
        String appid = user.getAppId();
        String openid = user.getOpenid();
        request.setAppId(appid);
        request.setSceneStr(eventKey);
        SimpleResult<WxQrcodeReplyInfoDTO> result = wxParamQrcodeService.queryOneReplyInfo(request);
        WxQrcodeReplyInfoDTO data = result.getData();
        log.error("QRCode replay data = {}", data);
        if (null == data || StringUtils.isBlank(data.getContent())) {
            log.info("未配置回复消息，参数二维码不回复消息！appid = {},eventKey = {},openid={},msg = {}", appid, eventKey, openid, result.getErrmsg());
            return;
        }
        //回复消息
        if (CustomMsgTypeEnum.text.getCode().equals(data.getMsgType())) {
            // 文本
            String content = replaceTextMsg(data.getContent(), user);
            wxMsgService.sendCustomerTextMsg(appid, openid, content);
        } else if (CustomMsgTypeEnum.image.getCode().equals(data.getMsgType())) {
            // 发送图文消息
            wxMsgService.sendConsumerImgMsg(appid, openid, data.getContent());
        } else if (CustomMsgTypeEnum.mpnews.getCode().equals(data.getMsgType())) {
            // 发送 msnews 消息
            wxMsgService.sendConsumerMpNewsMsg(appid, openid, data.getContent());
        } else {
            log.error("QRCode replay error , The msg type undefined! {}", data);
        }
    }

    /**
     * 替换 昵称和广告
     *
     * @param replyData
     * @param user
     * @return
     */
    private String replaceTextMsg(String replyData, WxUserInfoExp user) {
        if (StringUtil.isEmpty(replyData)) {
            return StringUtil.EMPTY_STRING;
        }
        //替换固定字符串消息
        replyData = replyData.replaceAll(PlaceholderConstants.NICK_NAME_PLACEHOLDER, user.getNickname());
        //替换动态文案 !!advert!!
        AppRequest appRequest = new AppRequest();
        appRequest.setAppId(user.getAppId());
        // 查出appid下的所有广告
        List<WxSubscribeReplyAdvertDTO> data = adverseService.queryAdvert(appRequest).getData();
        if (!CollectionUtils.isEmpty(data)) {
            //重新洗牌
            Collections.shuffle(data);
            WxSubscribeReplyAdvertDTO replyAdvert = data.get(0);
            replyData = replyData.replaceAll(PlaceholderConstants.ADVERT, "\n" + replyAdvert.getAdvert());
        } else {
            replyData = replyData.replaceAll(PlaceholderConstants.ADVERT, StringUtil.EMPTY_STRING);
        }
        return replyData;
    }

    /**
     * 扫渠道二维码通知立白
     *
     * @param appId        公众号ID
     * @param fromUserName 用户openId
     * @param eventKey     二维码渠道标识
     */
    private void qrsceneNotifyTheUser(String appId, String fromUserName, String eventKey) {
        if (StringUtils.isNotBlank(eventKey)) {
            NotifyUserActivityDTO notifyUserActivity = new NotifyUserActivityDTO();
            notifyUserActivity.setAppId(appId);
            notifyUserActivity.setOpenId(fromUserName);
            notifyUserActivity.setCodeType(eventKey);
            log.info("ParamQrcodeScanProcessor qrsceneNotifyTheUser notifyUserActivity=" + notifyUserActivity);
            externalSystemService.qrsceneNotifyTheUser(notifyUserActivity);
        }
    }

    @Override
    public String getEvent() {
        return EventTypeEnum.SCAN.getCode();
    }
}
